package com.young4j.springdemo.utils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author yf
 * @Date 2019/1/31 9:59
 **/
public class CollectionsUtils {
    /**
     * HashMap sortedByKey reverse and return treeMap
     * @param source
     * @return treeMap:{d=6, c=2, b=5, a=3}
     */
    public static Map treeMapSortByKey(Map<String,Integer> source) {
        Map<String, Integer> map = new TreeMap<>((m, n) -> n.compareTo(m));
        map.putAll(source);
        return map;
    }

    /**
     * HashMap sortedByValue and return ArrayList
     * @param source
     * @return
     */
    public static ArrayList<Map.Entry<String, Integer>> treeMapSortByValue(Map<String, Integer> source) {
        ArrayList<Map.Entry<String, Integer>> entries = new ArrayList<>(source.entrySet());
        entries.sort((m, n) -> m.getValue().compareTo(n.getValue()));
        return entries;
    }
    /**
     * HashMap sortedByKey reverse and return LinkedHashMap
     * @param source
     * @return linkedHashMap sorted by key:{d=6, c=2, b=5, a=3}
     */
    public static Map linkedHashMapSortedByKey(Map<String,Integer> source) {
        //sort by keys,and return a new LinkedHashMap,toMap() will returns HashMap by default,we need LinkedHashMap to keep the order.
        LinkedHashMap<String, Integer> linkedHashMapSortedByKey = source.entrySet().stream()
                .sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
        return linkedHashMapSortedByKey;
    }

    /**
     * HashMap sortedByValue reverse and return LinkedHashMap
     * @param source
     * @return linkedHashMap sorted by value:{d=6, b=5, a=3, c=2}
     */
    public static Map lickedHashMapSortedByValue(Map<String,Integer> source) {
        LinkedHashMap<String, Integer> linkedHashMapSortedByValue = source.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toMap(
                        Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new
                ));
        return linkedHashMapSortedByValue;
    }
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String,Integer>();
        map.put("b", 5);
        map.put("d", 6);
        map.put("c", 2);
        map.put("a", 3);
        Map target = CollectionsUtils.treeMapSortByKey(map);
        System.out.println("treeMap:" + target.toString());
        //sort by keys,and return a new LinkedHashMap,toMap() will returns HashMap by default,we need LinkedHashMap to keep the order.
        LinkedHashMap<String, Integer> linkedHashMapSortedByKey = map.entrySet().stream()
                .sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
        System.out.println("linkedHashMap sorted by key:" + linkedHashMapSortedByKey.toString());

        LinkedHashMap<String, Integer> lickedHashMapSortedByValue = map.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toMap(
                Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new
        ));
        System.out.println("linkedHashMap sorted by value:" + lickedHashMapSortedByValue.toString());
    }
}
